package com.ruoyi.erp.service.impl;

import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.erp.common.enums.OrderProductStatus;
import com.ruoyi.erp.domain.XzgOrderProduct;
import com.ruoyi.erp.domain.XzgProduct;
import com.ruoyi.erp.domain.dto.XzgOrderProductDto;
import com.ruoyi.erp.domain.dto.XzgOrderProductExcelDto;
import com.ruoyi.erp.domain.vo.XzgOrderProductVo;
import com.ruoyi.erp.mapper.XzgOrderProductMapper;
import com.ruoyi.erp.mapper.XzgProductMapper;
import com.ruoyi.erp.service.IXzgOrderProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

/**
 * @author qiuwencong
 * @Date 2022/1/5 8:43
 * @Package com.ruoyi.erp.service.impl
 * @Description
 */
@Service
public class XzgOrderProductServiceImpl implements IXzgOrderProductService {

    @Autowired
    private XzgOrderProductMapper orderProductMapper;

    @Autowired
    private XzgProductMapper productMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertOrderProduct(XzgOrderProduct product) {
        if (checkProduct(product.getOrderId(), product.getProductId()).booleanValue()) {
            throw new ServiceException("产品已存在");
        }
        checkStorage(product, product.getOrderProductId());
        return orderProductMapper.insertSelective(product);
    }

    @Override
    public int reduceStorage(Long productId, Integer actualNum, String username) {
        return productMapper.reduceStorage(productId, actualNum, username);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, List<String>> importOrderProducts(List<XzgOrderProductExcelDto> orderProducts, boolean updateSupport, Long orderId, String username) {
        List<String> insertSuccess = new ArrayList<>();
        List<String> updateSuccess = new ArrayList<>();
        List<String> fail = new ArrayList<>();
        for (XzgOrderProductExcelDto orderProduct : orderProducts) {
            // 产品不存在不插入
            XzgProduct product = productMapper.selectByCode(orderProduct.getProductCode());
            if (Objects.isNull(product)) {
                fail.add("编号为：" + orderProduct.getProductCode() + "的产品不存在");
                continue;
            }
            XzgOrderProduct existOrderProduct = orderProductMapper.selectByProductId(orderId, product.getProductId());
            // 已存在的订单产品需要判断是否能够修改
            if (Objects.isNull(existOrderProduct)) {
                XzgOrderProduct xzgOrderProduct = new XzgOrderProduct();
                xzgOrderProduct.setProductId(product.getProductId());
                xzgOrderProduct.setOrderId(orderId);
                xzgOrderProduct.setCreateBy(username);
                xzgOrderProduct.setCreateTime(new Date());
                conventOrderProduct(orderProduct, xzgOrderProduct, username);
                // 判断库存
                if (reduceStorage(product.getProductId(), xzgOrderProduct.getActualNum(), username) < 1) {
                    fail.add("编号为：" + orderProduct.getProductCode() + "的产品库存不足");
                } else {
                    orderProductMapper.insertSelective(xzgOrderProduct);
                    insertSuccess.add(orderProduct.getProductCode());
                }
            } else if (updateSupport) {
                Integer storage = orderProduct.getActualNum() - existOrderProduct.getActualNum();
                conventOrderProduct(orderProduct, existOrderProduct, username);
                if (reduceStorage(product.getProductId(), storage, username) < 1) {
                    fail.add("编号为：" + orderProduct.getProductCode() + "的产品库存不足");
                } else {
                    orderProductMapper.updateByPrimaryKeySelective(existOrderProduct);
                    updateSuccess.add(orderProduct.getProductCode());
                }
            } else {
                fail.add("编号为：" + orderProduct.getProductCode() + "的数据已存在");
            }
        }
        Map<String, List<String>> map = new HashMap<>(3);
        map.put("insert", insertSuccess);
        map.put("update", updateSuccess);
        map.put("fail", fail);
        return map;
    }

    @Override
    public Boolean checkProduct(Long orderId, Long productId) {
        return orderProductMapper.selectByOrderIdAndProductId(orderId, productId) > 0;
    }

    @Override
    public List<XzgOrderProductVo> selectOrderProductList(XzgOrderProductDto dto) {
        return orderProductMapper.selectOrderProductList(dto);
    }

    @Override
    public XzgOrderProductVo selectOrderProductById(Long orderProductId) {
        return orderProductMapper.selectByOrderProductId(orderProductId);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateOrderProduct(XzgOrderProduct product) {
        checkStorage(product, product.getOrderProductId());
        return orderProductMapper.updateByPrimaryKeySelective(product);
    }

    private void checkStorage(XzgOrderProduct product, Long orderProductId) {
        Integer storage = 0;
        if (Objects.nonNull(orderProductId)) {
            XzgOrderProduct xzgOrderProduct = orderProductMapper.selectByPrimaryKey(orderProductId);
            storage = product.getActualNum() - xzgOrderProduct.getActualNum();
        }
        if (reduceStorage(product.getProductId(), storage, product.getUpdateBy()) < 1) {
            throw new ServiceException("库存不足");
        }
        if (product.getProductNum() <= product.getActualNum()) {
            product.setStatus(OrderProductStatus.FINISHDE.getKey());
        } else {
            product.setStatus(OrderProductStatus.UNFINISHDE.getKey());
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteOrderProductById(Long[] orderProductIds, String username) {
        List<XzgOrderProduct> orderProducts = orderProductMapper.selectByIds(orderProductIds);
        for (XzgOrderProduct orderProduct : orderProducts) {
            productMapper.updateStorageByProductId(orderProduct.getProductId(), orderProduct.getActualNum(), username);
        }
        return orderProductMapper.logicDeleteOrderProductById(orderProductIds, username);
    }

    private void conventOrderProduct(XzgOrderProductExcelDto dto, XzgOrderProduct product, String username) {
        dto.setActualNum(dto.getActualNum() != null ? dto.getActualNum() : 0);
        dto.setProductNum(dto.getProductNum() != null ? dto.getProductNum() : 0);
        dto.setProductPrice(dto.getProductPrice() != null ? dto.getProductPrice() : new BigDecimal(0));
        product.setActualNum(dto.getActualNum());
        product.setDeleted("0");
        product.setDeliveryTime(dto.getDeliveryTime());
        product.setFinishTime(dto.getFinishTime());
        product.setProductNum(dto.getProductNum());
        product.setProductPrice(dto.getProductPrice());
        product.setTotalPrice(dto.getProductPrice().multiply(new BigDecimal(dto.getActualNum())));
        product.setUpdateBy(username);
        product.setUpdateTime(new Date());
        product.setRemark(dto.getRemark());
        product.setStatus(dto.getActualNum() >= dto.getProductNum() ? OrderProductStatus.FINISHDE.getKey() : OrderProductStatus.UNFINISHDE.getKey());
    }

}
